use crate::globals::POOL_ERRORS;


// TODO: nested error?
#[derive(Debug, Clone, thiserror::Error)]
pub enum TonglunError {
    #[error("Invalid value tag: {0}")]
    InvalidValueTag(u32),
    #[error("Runtime already registered: (name = {1}, address = {0})")]
    RuntimeAlreadyRegistered(usize, String),

    #[error("Out of memory")]
    OutOfMemory,

    #[error("Invalid UTF-8 string")]
    InvalidUtf8String,

    #[error("Invalid typecode: {0}")]
    InvalidTypecode(String),

    #[error("Runtime not found: {0}")]
    RuntimeNotFound(usize),

    #[error("Function already registered: {0}")]
    FunctionAlreadyRegistered(String),

    #[error("Function not found: {0}")]
    FunctionNotFound(String),

    #[error("Error not found: {0}")]
    ErrorNotFound(usize),

    #[error("Not enough buffer length: {0}")]
    NotEnoughBufferLength(usize),

    #[error("BindingError({language}): {message}")]
    BindingError {
        language: String,
        message: String,
    },
}

impl TonglunError {
    pub fn into_usize(self) -> usize {
        let mut lock = POOL_ERRORS.write();
        let entry = lock.alloc(self);
        entry.to_usize()
    }
}
